home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * C F O R M S . C
- * ---------------
- *
- * Description:
- *
- * Included functions:
- *
- * Misc functions
- * --------------
- * cforms_end - Stop CForms
- * cforms_init - Initiate CForms
- * cforms_refresh - Refresh the CForms screen.
- * cforms_system - Call the operating system
- *
- * Picture functions
- * -----------------
- * pic_call - Call picture
- * pic_clear - Clear all fields for picture
- * pic_leave - Leave current picture
- * picture - Get picture with name
- *
- * Field functions
- * ---------------
- * field - Get field with name
- * fld_isempty - Check if field is empty
- * fld_first - Find first field of picture
- * fld_next - Find next field for picture
- * fld_previous - Find previous field for picture
- * fld_left - Find left field
- * fld_right - Find right field
- * fld_up - Find field above current
- * fld_down - Find field below current
- * fld_set - Set value for field
- * fld_nset - Set value for field but max n chars
- * fld_get - Get value of field
- * fld_len - Return length of field
- * fld_name - Return name of field
- * fld_ismodified - Return true if field has been modified since fld_set
- * fld_sattr - Set attributes for field.
- * fld_cattr - Clear attributes for field.
- * fld_touch - Make field not modified
- *
- * General functions
- * -----------------
- * message - Give message (line 24)
- * strequ - Compqare two strings, but case insensitive
- *
- * Local functions
- * ---------------
- * hdl_field - This is the head function for cforms
- * getraw - Get raw key
- * draw_picture - Draw picture with fields
- * draw_field - Draw field.
- * check_int - Checkfunction for integer fields
- * check_alnum - -''- alphanumeric fields
- * check_char - -''- character fields
- * adjust_right - Adjust string to right
- * generate_event - Raise event and call event functions and handle
- * if field is moved.
- * raw_event - Raise event and call event functions
- *
- * Global variables:
- * none
- *
- * Revision:
- * Ver Date By Reason
- * --- ---- -- ------
- * 1.00 900629 Lars Berntzon Created
- *
- ****************************************************************************/
-
- #ifndef lint
- static volatile char sccs_id[] = "@(#) cflib.c,v 1.23 1993/07/21 01:15:18 lasse Exp";
- #endif
-
- #include "config.h"
- #include "cforms.h"
-
- #define KEY_CTRL(c) (toupper(c) - 'A' + 1)
-
- #ifndef ACS_ULCORNER
- #define ACS_ULCORNER '+'
- #endif
- #ifndef ACS_LLCORNER
- #define ACS_LLCORNER '+'
- #endif
- #ifndef ACS_URCORNER
- #define ACS_URCORNER '+'
- #endif
- #ifndef ACS_LRCORNER
- #define ACS_LRCORNER '+'
- #endif
- #ifndef ACS_HLINE
- #define ACS_HLINE '-'
- #endif
- #ifndef ACS_VLINE
- #define ACS_VLINE '|'
- #endif
-
-
- /* G l o b a l v a r i a b l e s */
-
- struct global _cf_globals; /* Current field and picture */
-
- /* L o c a l v a r i a b l e s */
-
- #ifdef SIGNAL_INT
- static int sigcatch(int sig);
- #else
- static void sigcatch(int sig);
- #endif
- static int _message(const char *fmt, va_list arg);
- static int check_int(int *ch, char *txt, int *pos, int len);
- static int check_alnum(int *ch, char *txt, int *pos, int len);
- static int check_char(int *ch, char *txt, int *pos, int len);
- static int draw_picture(struct picture *pic);
- static void draw_field(struct field *fld);
- static void move_to_field(struct field *fld);
- static int hdl_field(struct field *fld);
- static int adjust_right(char *txt, int len);
- static void debug(char *fmt, ...);
- static int generate_event(int ev_type, int ev_spec, int ev_code);
- static int raw_event(int ev_type, int ev_spec, int ev_code);
-
- static struct picture *pstack[200];
- static int pstackp = 0;
- static int cforms_inited = FALSE;
-
-
- /******************************************************************************
- *
- * C F O R M S _ I N I T
- * ---------------------
- * Description:
- * Initialize cforms. (currently only initscr).
- *
- *****************************************************************************/
- int
- cforms_init(void)
- {
- int pic, fld;
- int m;
-
- cforms_inited = TRUE;
-
- signal(SIGINT, sigcatch);
-
- if (initscr() == NULL) {
- return FAIL;
- }
- keypad(stdscr,TRUE);
-
- /*
- * Save picture pointer for every field.
- */
- for(m = 0; _cf_modules[m] != NULL; m++)
- {
- for(pic = 0; pic < _cf_modules[m]->n_pictures; pic++)
- {
- for(fld = 0; fld < _cf_modules[m]->picture[pic].n_fields; fld++)
- {
- _cf_modules[m]->picture[pic].field[fld].picture =
- &_cf_modules[m]->picture[pic];
- }
- }
- }
-
- raw();
- noecho();
-
- /*
- * Set up some default keys for field editing.
- */
- _cf_globals.bs = '\b';
- _cf_globals.del1 = 'D' & 0x1F;
- _cf_globals.del2 = 127;
- _cf_globals.kill = 'K' & 0x1F;
- _cf_globals.clear = 'U' & 0x1F;
-
- return OK;
- }
-
- /******************************************************************************
- *
- * C F O R M S _ E N D
- * -------------------
- *
- * Description:
- * Turns off cforms.
- *
- *****************************************************************************/
- int
- cforms_end(void)
- {
- cforms_inited = FALSE;
- move(23, 1);
- refresh();
- endwin();
-
- return OK;
- }
-
- /******************************************************************************
- *
- * C F O R M S _ R E F R E S H
- * ---------------------------
- *
- * Description:
- * Refresh the CForms application window.
- *
- *****************************************************************************/
- void
- cforms_refresh(void)
- {
- int i;
-
- clear();
- for(i = 0; i < pstackp; i++) {
- debug("drawing picture %d", i);
- draw_picture(pstack[i]);
- }
- generate_event(EVENT_REFRESH, 0, 0);
- }
-
- /*******************************************************************************
- *
- * C F O R M S _ S Y S T E M
- * -------------------------
- *
- *
- * Description:
- * Execute an operating system command from CForms without destroying
- * the screen.
- *
- *
- * Input:
- * command - OS command to execute.
- *
- * Return:
- * Integer return value from system command.
- *
- ******************************************************************************/
- int
- cforms_system(const char *command, const char *prompt)
- {
- int result;
- char ch;
-
- if (command == NULL) {
- return 0;
- }
- /*
- * Clean the picture.
- */
- clear();
- refresh();
- endwin();
-
- putenv("IFS= \t\n"); /* Make system() a bit more secure */
- result = system(command);
-
- if (prompt != NULL)
- {
- write(1, prompt, strlen(prompt));
- while(read(0, &ch, 1) == 1 && ch != '\n')
- ;
- }
-
- initscr();
- keypad(stdscr,TRUE);
-
- cforms_refresh();
-
- return result;
- }
-
-
- /*******************************************************************************
- *
- * P I C _ C A L L
- * ---------------
- *
- *
- * Description:
- * This is the entry point for application into CForms
- *
- * Input:
- * pic - Picture to call
- * field_name - Name of field to start at, (NULL means first field).
- *
- * Global:
- * _cf_globals.picture - Is set up to point to this picture
- *
- ******************************************************************************/
- int
- pic_call(struct picture *pic, const char *field_name)
- {
- struct global old_globals = _cf_globals;
-
- if (cforms_inited == FALSE) {
- fprintf(stderr, "** CForms not initialized **\n");
- return FAIL;
- }
-
- if (pic == NULL) return FAIL;
-
- _cf_globals.picture = pic;
- _cf_globals.field = NULL;
-
- /*
- * Keep track of how pictures are stacked in case of a refresh
- * is orderded from keyboard.
- */
- pstack[pstackp++] = pic;
-
- /*
- * Paint the new picture.
- */
- draw_picture(pic);
-
- /*
- * The event draw is special in that it is only valid for pictures.
- */
- generate_event(EVENT_DRAW, 0, 0);
-
- /*
- * If field is still not set in EVENT_DRAW, go to proper one.
- */
- if (_cf_globals.field == NULL) {
- if (field_name) move_to_field(field(field_name));
- else move_to_field(fld_first());
- }
-
- /*
- * Make sure there really exists a field to move to in
- * picture.
- */
- if (_cf_globals.field != NULL)
- {
- while(_cf_globals.leave_picture == FALSE)
- {
- hdl_field(_cf_globals.field);
- }
- generate_event(EVENT_EXIT, 0, 0);
- }
-
- /*
- * Redraw the picture picture that was active before
- * this one was called and make that old one active again.
- */
- _cf_globals = old_globals;
-
- if (_cf_globals.picture)
- {
- draw_picture(_cf_globals.picture);
- generate_event(EVENT_REFRESH, 0, 0);
- }
- pstackp--;
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * P I C T U R E
- * -------------
- *
- * Description:
- * Finds a picture with name as described by arguments in printf format.
- *
- ******************************************************************************/
- struct picture *
- picture(const char *fmt, ...)
- {
- static char pic_name[100];
- va_list arg;
- int i;
- int m;
-
- va_start(arg, fmt);
- vsprintf(pic_name, fmt, arg);
- va_end(arg);
-
- /*
- * Loop through all modules and their pictures
- * to find name.
- */
- for(m = 0; _cf_modules[m] != 0; m++)
- {
- for(i = 0; i < _cf_modules[m]->n_pictures; i++)
- {
- if (strequ(pic_name, _cf_modules[m]->picture[i].name) == 0)
- {
- return &_cf_modules[m]->picture[i];
- }
- }
- }
- return NULL;
- }
-
-
- /*******************************************************************************
- *
- * P I C _ L E A V E
- * -----------------
- *
- * Description:
- * Leave picture uppon exit of current event.
- *
- ******************************************************************************/
- int
- pic_leave(void)
- {
- _cf_globals.leave_picture = TRUE;
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * P I C _ C L E A R
- * -----------------
- *
- * Description:
- * Clear all field of picture 'pic'.
- *
- ******************************************************************************/
- int
- pic_clear(struct picture *pic)
- {
- int i, n;
-
- if (pic == NULL) pic = _cf_globals.picture;
- if (pic == NULL) return FAIL;
-
- for(i = 0; i < pic->n_fields; i++) {
- pic->field[i].data[0] = 0;
- }
-
- if (_cf_globals.picture == pic) {
- for(i = 0; i < pic->n_fields; i++) {
- move(pic->field[i].pos.y + pic->y, pic->field[i].pos.x + pic->x);
- for(n = 0; n < pic->field[i].len; n++) {
- addch(' ');
- }
- }
- }
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * H D L _ F I E L D
- * -----------------
- *
- * Description:
- * Handles the intput of one field. When ever a event is generated
- * this function returns to pic_call which should handle the results
- * of this event. Also when a field is moved this function will return.
- *
- * Arguments:
- * fld - Pointer to field to handle.
- *
- ******************************************************************************/
- static int
- hdl_field(struct field *fld)
- {
- int (*check_p)();
- int x, y, ch, i, pos = 0;
- struct field *tmp_fld;
-
- move((y = fld->pos.y) + fld->picture->y,
- (x = fld->pos.x) + fld->picture->x);
-
- /*
- * Setup which function to handle key input to field.
- */
- switch(fld->type & FLD_TYPE)
- {
- case FLD_CHAR:
- check_p = check_char;
- break;
-
- case FLD_ALNUM:
- check_p = check_alnum;
- break;
-
- case FLD_INT:
- check_p = check_int;
- break;
-
- default:
- message("Illegal field type, probably a bug in CForms");
- }
-
- /*
- * Pad field with spaces after null.
- */
- i = strlen(fld->data);
- memset(fld->data + i, ' ', fld->len - i);
- fld->data[fld->len] = 0;
-
- /*
- * Handle keys pressed by user.
- */
- while (refresh(), (ch = getch()) != EOF)
- {
- message_nr("");
-
- /*
- * Second try to generated an event for the key pressed.
- */
- if (generate_event(EVENT_KEY, KEY_ANY, ch))
- {
- break;
- }
- /*
- * Second try to generated an event for the key pressed.
- */
- else if (generate_event(EVENT_KEY, ch, ch))
- {
- break;
- }
- /*
- * If CTRL-W then do refresh.
- */
- else if (ch == KEY_CTRL('w'))
- {
- cforms_refresh();
- }
- /*
- * If newline adjust the field if it should be.
- */
- else if (ch == '\n')
- {
- if (fld->type & FLD_RIGHT)
- {
- adjust_right(fld->data, fld->len);
- }
- }
- /*
- * Move one pos left.
- */
- else if (ch == KEY_LEFT)
- {
- if (pos <= 0 || (fld->flags & FLD_PROTECTED))
- {
- if (generate_event(EVENT_PREVIOUS, 0, 0))
- {
- break;
- }
- else if (tmp_fld = fld_left(_cf_globals.field))
- {
- move_to_field(tmp_fld);
- break;
- }
- else message("Can't move left");
- }
- else {
- pos--;
- }
- }
- /*
- * Move one pos right.
- */
- else if (ch == KEY_RIGHT)
- {
- if (pos >= fld->len - 1 || (fld->flags & FLD_PROTECTED))
- {
- if (generate_event(EVENT_NEXT, 0, 0))
- {
- break;
- }
- else if (tmp_fld = fld_right(_cf_globals.field))
- {
- move_to_field(tmp_fld);
- break;
- }
- else message("Can't move right");
- }
- else
- {
- pos++;
- }
- }
- /*
- * From here on data in the field is actually modified,
- * unless if protected in case it is not allowed.
- */
- else if (fld->flags & FLD_PROTECTED)
- {
- message("No input allowed");
- }
- /*
- * Backspace.
- */
- else if (ch == _cf_globals.bs)
- {
- if (pos > 0) {
- for(i = pos; i < fld->len; i++)
- {
- fld->data[i - 1] = fld->data[i];
- }
- fld->data[i - 1] = ' ';
- pos--;
- }
- fld->modified = 1;
- }
- /*
- * Check if CTRL-D or delete.
- */
- else if (ch == _cf_globals.del1 || ch == _cf_globals.del2)
- {
- for(i = pos + 1; i < fld->len; i++)
- {
- fld->data[i - 1] = fld->data[i];
- }
- fld->data[i - 1] = ' ';
-
- fld->modified = 1;
- }
- /*
- * CTRL-K clears the rest of the field.
- */
- else if (ch == _cf_globals.kill)
- {
- for(i = pos; i < fld->len; i++)
- {
- fld->data[i] = ' ';
- }
-
- fld->modified = 1;
- }
- /*
- * CTRL-U clears the whole field.
- */
- else if (ch == _cf_globals.clear)
- {
- pos = 0;
- for(i = pos; i < fld->len; i++)
- {
- fld->data[i] = ' ';
- }
-
- fld->modified = 1;
- }
- /*
- * Control characters ?, no no.
- */
- else if (!isprint(ch))
- {
- message("Unknown key (%d)", ch);
- }
- /*
- * This is actually where data gets written into the field.
- */
- else if (check_p(&ch, fld->data, &pos, fld->len))
- {
- if (fld->flags & FLD_UPPERCASE) ch = toupper(ch);
- for(i = fld->len - 1; i > pos; i--)
- {
- fld->data[i] = fld->data[i - 1];
- }
- fld->data[pos] = ch;
- if (pos < fld->len - 1) pos++;
- fld->modified = 1;
- }
-
- draw_field(fld);
- move(y + fld->picture->y, x + fld->picture->x + pos);
- }
-
- if (fld->type & FLD_RIGHT)
- {
- adjust_right(fld->data, fld->len);
- }
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * M E S S A G E, M E S S A G E _ N R
- * ----------------------------------
- *
- * Description:
- * Give message on bottom screen line. Work the same way as printf.
- * message_nr works the same as message but gives no refresh.
- *
- ******************************************************************************/
- int
- message(const char *fmt, ...)
- {
- va_list arg;
- va_start(arg, fmt);
- _message(fmt, arg);
- va_end(arg);
- refresh();
- return OK;
- }
-
- int
- message_nr(const char *fmt, ...)
- {
- va_list arg;
- va_start(arg, fmt);
- _message(fmt, arg);
- va_end(arg);
- return OK;
- }
-
- static int
- _message(const char *fmt, va_list arg)
- {
- static char msg_str[160];
- char tmp_str[160];
- int x, y;
-
- getyx(stdscr, y, x);
-
- move(23, 1);
- if (fmt != NULL) {
- vsprintf(tmp_str, fmt, arg);
- sprintf(msg_str, "%-50.50s", tmp_str);
- }
- addstr(msg_str);
- move(y, x);
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * C H E C K *
- * -----------
- *
- * Description:
- * Various check functions depending of type of field.
- * If function returnes TRUE, the char ch is put into field.
- *
- ******************************************************************************/
- static int
- check_int(int *ch, char *txt, int *pos, int len)
- {
- int i;
- if (isdigit(*ch)) {
- return TRUE;
- }
-
- if (isspace(*ch)) {
- for(i = 0; i < *pos; i++) {
- if (!isspace(txt[i])) {
- message("No space in middle of value");
- return FALSE;
- }
- }
- return TRUE;
- }
- message ("Must be digit");
- return FALSE;
- }
-
- static int
- check_alnum(int *ch, char *txt, int *pos, int len)
- {
- if (isalnum(*ch) || isspace(*ch)) return TRUE;
- message("Must be alphanumeric");
- return FALSE;
- }
-
- static int
- check_char(int *ch, char *txt, int *pos, int len)
- {
- if (isprint(*ch)) return TRUE;
- message("Must be printable");
- return FALSE;
- }
-
-
- /*******************************************************************************
- *
- * A D J U S T _ R I G H T
- * -----------------------
- *
- * Description:
- * Adjust a text to the right
- *
- ******************************************************************************/
- static int
- adjust_right(char *txt, int len)
- {
- int last_space = len - 1;
-
- while(isspace(txt[last_space]) && last_space >= 0)
- last_space--;
- last_space++;
- memcpy(txt + len - last_space, txt, last_space);
- memset(txt, ' ', len - last_space);
-
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * G E N E R A T E _ E V E N T
- * ---------------------------
- *
- * Description:
- * Calls raw_event to make the event execute. After that it checks if
- * field has been moved in case move_to_field is called.
- *
- * Input:
- * ev_type - Event type, ex. EVENT_KEY, EVENT_ENTRY.
- * ev_spec - Specified for type.
- * ev_code - Code of event (not for all types), ex KEY_UP.
- *
- * Return:
- * Boolean, TRUE if event code was found and called. Events are not
- * called for 'event forget' statements (function = NULL).
- *
- ******************************************************************************/
- static int
- generate_event(int ev_type, int ev_spec, int ev_code)
- {
- if (raw_event(ev_type, ev_spec, ev_code) == FALSE)
- {
- return FALSE;
- }
-
- if (_cf_globals.move_field != NULL)
- {
- move_to_field(_cf_globals.move_field);
- }
-
- return TRUE;
- }
-
-
- /*******************************************************************************
- *
- * R A W _ E V E N T
- * -----------------
- *
- * Description:
- * Generate a event of type and with code, and calls first function
- * for field or picture that should respond to the event.
- *
- * Input:
- * ev_type - Event type, ex. EVENT_KEY, EVENT_ENTRY.
- * ev_spec - Event specifier.
- * ev_code - Code of event (not for all types), ex KEY_UP.
- *
- * Return:
- * Boolean, TRUE if event code was found and called. Events are not
- * called for 'event forget' statements (function = NULL).
- *
- ******************************************************************************/
- int
- raw_event(int ev_type, int ev_spec, int ev_code)
- {
- int i, m;
-
- /*
- * Check if field has handler for event, exept for DRAW
- * events that is only sent to picture and module event handlers.
- */
- if (ev_type != EVENT_DRAW)
- {
- for(i = 0; _cf_globals.field && i < _cf_globals.field->n_events; i++) {
- if (_cf_globals.field->event[i].type == ev_type &&
- _cf_globals.field->event[i].code == ev_spec) {
- if (_cf_globals.field->event[i].func == NULL)
- {
- return FALSE;
- }
- (*_cf_globals.field->event[i].func)(ev_code);
- return TRUE;
- }
- }
- }
-
- /*
- * The field did not have a handler for the event, lets check if
- * the picture has.
- */
- for(i = 0; _cf_globals.picture && i < _cf_globals.picture->n_events; i++) {
- if (_cf_globals.picture->event[i].type == ev_type &&
- _cf_globals.picture->event[i].code == ev_spec) {
- if (_cf_globals.picture->event[i].func == NULL) {
- return FALSE;
- }
- (*_cf_globals.picture->event[i].func)(ev_code);
- return TRUE;
- }
- }
-
- /*
- * The picture did not have a handler for the event, lets check if
- * the module has.
- */
- for(i = 0; i < _cf_globals.picture->module->n_events; i++) {
- if (_cf_globals.picture->module->event[i].type == ev_type &&
- _cf_globals.picture->module->event[i].code == ev_spec) {
- if (_cf_globals.picture->module->event[i].func == NULL) {
- return FALSE;
- }
- (*_cf_globals.picture->module->event[i].func)(ev_code);
- return TRUE;
- }
- }
-
- /*
- * This module did not have a handler for the event, lets check if
- * there is a global event handler.
- */
- for(m = 0; _cf_modules[m] != 0; m++)
- {
- for(i = 0; i < _cf_modules[m]->n_events; i++)
- {
- if (_cf_modules[m]->event[i].global != 0 &&
- _cf_modules[m]->event[i].type == ev_type &&
- _cf_modules[m]->event[i].code == ev_spec) {
- if (_cf_modules[m]->event[i].func == NULL) {
- return FALSE;
- }
- (*_cf_modules[m]->event[i].func)(ev_code);
- return TRUE;
- }
- }
- }
-
- /*
- * No, no event handlers existed for this type of event.
- */
-
- return FALSE;
- }
-
-
- /*******************************************************************************
- *
- * F L D _ M O V E
- * ---------------
- *
- * Description:
- * Move to field
- *
- * Input:
- * fld - Field to move to.
- *
- * Return:
- * field moved to (or current if forbidden field).
- *
- ******************************************************************************/
- struct field *
- fld_move(struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld->flags & FLD_FORBIDDEN) return _cf_globals.field;
-
- _cf_globals.move_field = fld;
-
- return _cf_globals.move_field;
- }
-
-
- /*******************************************************************************
- *
- * F L D _ G E T
- * -------------
- *
- * Description:
- * Return text in field.
- *
- ******************************************************************************/
- const char *
- fld_get(const struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld) return fld->data;
-
- return "";
- }
-
- /*******************************************************************************
- *
- * F L D _ G E T _ T R I M M E D
- * -----------------------------
- *
- * Description:
- * Return text in field but with trimmed blanks at beginning and end.
- *
- ******************************************************************************/
- char *
- fld_get_trimmed(const struct field *fld)
- {
- static char txt[1024];
- char *p;
- if (fld == NULL) fld = _cf_globals.field;
-
- if (fld && fld->data)
- {
- for(p = fld->data; isspace(*p); p++)
- ;
- strcpy(txt, p);
- for (p = txt + strlen(txt) - 1; isspace(*p) && p >= txt; p--)
- ;
- *(p + 1) = 0;
- }
- else {
- txt[0] = 0;
- }
-
- return txt;
- }
-
-
-
- /*******************************************************************************
- *
- * F L D _ S E T
- * -------------
- *
- * Description:
- * Set value for field.
- *
- ******************************************************************************/
- int
- fld_set(struct field *fld, const char *data)
- {
- int i;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return FAIL;
-
- memset(fld->data, ' ', fld->len);
- i = strlen(data);
- if (i > fld->len) i = fld->len;
- strncpy(fld->data, data, i);
- fld->modified = 0;
-
- if (fld->picture == _cf_globals.picture) {
- draw_field(fld);
- refresh();
- }
-
- return OK;
- }
-
-
- /*******************************************************************************
- *
- * F L D _ N S E T
- * ---------------
- *
- * Description:
- * Copy at most 'n' chars from input and set field to that.
- *
- ******************************************************************************/
- int
- fld_nset(struct field *fld, const char *data, int n)
- {
- char tmpstr[200];
- strncpy(tmpstr, data, n);
- tmpstr[n] = 0;
- return fld_set(fld, tmpstr);
- }
-
-
- /*******************************************************************************
- *
- * F L D _ L E N
- * -------------
- *
- * Description:
- * Return length of field.
- *
- ******************************************************************************/
- int
- fld_len(const struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return 0;
- return fld->len;
- }
- /*******************************************************************************
- *
- * F L D _ N A M E
- * ---------------
- *
- * Description:
- * Return name of field.
- *
- ******************************************************************************/
- const char *
- fld_name(const struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return 0;
- return fld->name;
- }
-
- /*******************************************************************************
- *
- * F L D _ I S M O D I F I E D
- * ---------------------------
- *
- * Description:
- * Return TRUE if field has been modified since last fld_set.
- *
- ******************************************************************************/
- int
- fld_ismodified(const struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return 0;
- return fld->modified;
- }
-
- /*******************************************************************************
- *
- * F L D _ S A T T R
- * -----------------
- *
- * Description:
- * Set attributes for field.
- *
- * Arguments:
- * attr - Bitmask of attributes to add to field.
- *
- * Return none
- *
- ******************************************************************************/
- void
- fld_sattr(struct field *fld, unsigned long attr)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return;
- fld->flags |= attr;
- if (fld->picture == _cf_globals.picture) {
- draw_field(fld);
- refresh();
- }
- }
-
- /*******************************************************************************
- *
- * F L D _ C A T T R
- * -----------------
- *
- * Description:
- * Clear attributes for field.
- *
- * Arguments:
- * attr - Bitmask of attributes to clear from field.
- *
- * Return none
- *
- ******************************************************************************/
- void
- fld_cattr(struct field *fld, unsigned long attr)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return;
- fld->flags &= ~attr;
- if (fld->picture == _cf_globals.picture) {
- draw_field(fld);
- refresh();
- }
- }
-
- /*******************************************************************************
- *
- * F L D _ T O U C H
- * -----------------
- *
- * Description:
- * Make field not modified.
- *
- ******************************************************************************/
- void
- fld_touch(struct field *fld)
- {
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return;
- fld->modified = 0;
- }
-
-
- /*******************************************************************************
- *
- * F I E L D
- * ---------
- *
- * Description:
- * Return pointer to field with name. Name works as printf.
- *
- ******************************************************************************/
- struct field *
- field(const char *fmt, ...)
- {
- static char field_name[100];
- struct picture *pic;
- va_list arg;
- char *p;
- int i;
-
- va_start(arg, fmt);
- vsprintf(field_name, fmt, arg);
- va_end(arg);
-
- if (p = (char*)strchr(field_name, ':')) {
- *p++ = 0;
- pic = picture(field_name);
- }
- else {
- pic = _cf_globals.picture;
- p = field_name;
- }
-
- if (pic == NULL) return NULL;
-
- for(i = 0; i < pic->n_fields; i++) {
- if(strequ(p, pic->field[i].name) == 0) return &pic->field[i];
- }
-
- return NULL;
- }
-
- /*******************************************************************************
- *
- * S T R E Q U
- * -----------
- *
- * Description:
- * Case insensitive strcmp.
- *
- ******************************************************************************/
- int
- strequ(const char *s1, const char *s2)
- {
- while(*s1 && toupper(*s1) == toupper(*s2))
- s1++, s2++;
-
- return toupper(*s1) - toupper(*s2);
- }
-
-
- /*******************************************************************************
- *
- * F L D _ L E F T
- * ---------------
- *
- * Description:
- * Return pointer to a field left of 'fld'.
- *
- ******************************************************************************/
- struct field *
- fld_left(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (fld != &_cf_globals.picture->field[i] &&
- _cf_globals.picture->field[i].pos.x < fld->pos.x)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (fld->pos.x - _cf_globals.picture->field[i].pos.x) << 9;
- dist += abs(fld->pos.y - _cf_globals.picture->field[i].pos.y);
- if (dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ R I G H T
- * -----------------
- *
- * Description:
- * Return pointer to a field right of 'fld'.
- *
- ******************************************************************************/
- struct field *
- fld_right(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (fld != &_cf_globals.picture->field[i] &&
- _cf_globals.picture->field[i].pos.x > fld->pos.x)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (_cf_globals.picture->field[i].pos.x - fld->pos.x) << 9;
- dist += abs(fld->pos.y - _cf_globals.picture->field[i].pos.y);
- if (dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ D O W N
- * ---------------
- *
- * Description:
- * Return a pointer to field below 'fld'.
- *
- ******************************************************************************/
- struct field *
- fld_down(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (fld != &_cf_globals.picture->field[i] &&
- _cf_globals.picture->field[i].pos.y > fld->pos.y)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (_cf_globals.picture->field[i].pos.y - fld->pos.y) << 9;
- dist += abs(_cf_globals.picture->field[i].pos.x - fld->pos.x);
- if (dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ U P
- * -----------
- *
- * Description:
- * Return pointer to field above 'fld'.
- *
- ******************************************************************************/
- struct field *fld_up(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (fld != &_cf_globals.picture->field[i] &&
- _cf_globals.picture->field[i].pos.y < fld->pos.y)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (fld->pos.y - _cf_globals.picture->field[i].pos.y) << 9;
- dist += abs(_cf_globals.picture->field[i].pos.x - fld->pos.x);
- if (dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ F I R S T
- * -----------------
- *
- * Description:
- * Find first field in picture.
- *
- ******************************************************************************/
- struct field *
- fld_first(void)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = _cf_globals.picture->field[i].pos.y << 9;
- dist += _cf_globals.picture->field[i].pos.x;
- if (dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
-
- return found;
- }
-
-
- /*******************************************************************************
- *
- * F L D _ L A S T
- * ---------------
- *
- * Description:
- * Find last field in picture.
- *
- ******************************************************************************/
- struct field *
- fld_last(void)
- {
- int i;
- int max_dist = -1;
- int dist;
- struct field *found = NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = _cf_globals.picture->field[i].pos.y << 9;
- dist += _cf_globals.picture->field[i].pos.x;
- if (dist > max_dist)
- {
- max_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ N E X T
- * ---------------
- *
- * Description:
- * Find next field in picture.
- *
- ******************************************************************************/
- struct field *
- fld_next(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (_cf_globals.picture->field[i].pos.y - fld->pos.y)<< 9;
- dist += _cf_globals.picture->field[i].pos.x - fld->pos.x;
-
- if (dist > 0 && dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ P R E V I O U S
- * -----------------------
- *
- * Description:
- * Find previoud field in picture.
- *
- ******************************************************************************/
- struct field *fld_previous(const struct field *fld)
- {
- int i;
- int min_dist = 1000000;
- int dist;
- struct field *found = NULL;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) fld = fld_first();
- if (fld == NULL) return NULL;
-
- for(i = 0; i < _cf_globals.picture->n_fields; i++)
- {
- if (_cf_globals.picture->field[i].flags & FLD_FORBIDDEN) continue;
-
- dist = (fld->pos.y - _cf_globals.picture->field[i].pos.y) << 9;
- dist += fld->pos.x - _cf_globals.picture->field[i].pos.x;
-
- if (dist > 0 && dist < min_dist)
- {
- min_dist = dist;
- found = &_cf_globals.picture->field[i];
- }
- }
-
- return found;
- }
-
- /*******************************************************************************
- *
- * F L D _ I S E M P T Y
- * ---------------------
- *
- * Description:
- * Return true if field contains only space or nulls.
- *
- ******************************************************************************/
- int
- fld_isempty(const struct field *fld)
- {
- int i;
-
- if (fld == NULL) fld = _cf_globals.field;
- if (fld == NULL) return TRUE;
-
- for(i = 0; i < fld->len; i++)
- {
- if (fld->data[i] == 0) return TRUE;
- if (!isspace(fld->data[i])) return FALSE;
- }
- return TRUE;
- }
-
- /*******************************************************************************
- *
- * D R A W _ P I C T U R E
- * -----------------------
- *
- * Description:
- * Draw all literals and fields in a picture.
- *
- ******************************************************************************/
- static int
- draw_picture(struct picture *pic)
- {
- int n;
- int r;
- int c;
- char space[400];
-
-
- if (pic == NULL) return FAIL;
-
- /*
- * Calculate blank it first.
- */
- memset(space, ' ', pic->width);
- space[pic->width] = 0;
-
- for(r = pic->y; r < pic->y + pic->height; r++) {
- move(r, pic->x);
- addstr(space);
- }
- debug("$cleared window size");
-
- if (pic->flags & PIC_FRAME)
- {
- for(r = pic->y; r < pic->y + pic->height; r++) {
- move(r, pic->x);
- addch(ACS_VLINE);
- move(r, pic->x + pic->width - 1);
- addch(ACS_VLINE);
- }
-
- for(c = pic->x; c < pic->x + pic->width; c++) {
- move(pic->y, c);
- addch(ACS_HLINE);
- move(pic->y + pic->height - 1, c);
- addch(ACS_HLINE);
- }
- move(pic->y, pic->x); addch(ACS_ULCORNER);
- move(pic->y, pic->x + pic->width - 1); addch(ACS_URCORNER);
- move(pic->y + pic->height - 1, pic->x); addch(ACS_LLCORNER);
- move(pic->y + pic->height - 1, pic->x + pic->width - 1); addch(ACS_LRCORNER);
- }
- debug("$drawn frame");
-
- for(n = 0; n < pic->n_literals; n++)
- {
- move(pic->literal[n].pos.y + pic->y, pic->literal[n].pos.x + pic->x);
- addstr(pic->literal[n].value);
- }
- debug("$drawn %d literals", n);
-
- for(n = 0; n < pic->n_fields; n++)
- {
- draw_field(&pic->field[n]);
- }
- debug("$drawn %d fields", n);
-
- message_nr(NULL);
-
- return OK;
- }
-
- /******************************************************************************
- *
- * S I G C A T C H
- * ---------------
- * Description:
- * Catches a signal, cleans up and exits.
- *
- *****************************************************************************/
- #ifdef SIGNAL_INT
- static int
- #else
- static void
- #endif
- sigcatch(int sig)
- {
- cforms_end();
- exit(1);
- #ifdef SIGNAL_INT
- return 0; /* Just to shut up compiler */
- #endif
- }
- /******************************************************************
- * D R A W _ F I E L D
- * -------------------
- * Decription:
- * Write field to screen.
- *
- * Arguments:
- * fld - Pointer to field.
- *
- * Return:
- * none
- *
- ******************************************************************/
- static void
- draw_field(struct field *fld)
- {
- if (fld == NULL || fld->picture == NULL) {
- message("(internal error: field with unknown picture)");
- return;
- }
-
- if (fld->lvalue)
- {
- move(fld->pos.y + fld->picture->y,
- fld->pos.x - strlen(fld->lvalue) + fld->picture->x);
- addstr(fld->lvalue);
- }
-
- if (fld->rvalue) {
- move(fld->pos.y + fld->picture->y,
- fld->pos.x + fld->len + fld->picture->x);
- addstr(fld->rvalue);
- }
-
- if ((fld->flags & FLD_INVISIBLE) == 0)
- {
- if (fld->flags & FLD_HIGHLIGHT) {
- standout();
- }
-
- move(fld->pos.y + fld->picture->y, fld->pos.x + fld->picture->x);
- addstr(fld->data);
-
- if (fld->flags & FLD_HIGHLIGHT) {
- standend();
- }
- }
- }
-
- static void
- debug(char *fmt, ...)
- {
- static char init; /* This is just a dummy address holder */
- static char *env = &init;
- static FILE *log;
- va_list arg;
- extern unsigned sleep(unsigned);
-
- /*
- * Get environment first time.
- */
- if (env == &init) {
- env = getenv("CFDEBUG");
-
- /*
- * Open file first time.
- */
- if (env) {
- if ((log = fopen("CForms.log", "w")) != NULL) {
- message("(started debug in CForms.log)");
- }
- }
- }
-
-
- /*
- * Print debug message if env set.
- */
- if (env && log)
- {
- /*
- * Write message.
- */
- if (fmt[0] == '$') {
- sleep (1);
- refresh();
- fmt++;
- }
- va_start(arg, fmt);
- vfprintf(log, fmt, arg);
- fprintf(log, "\n");
- fflush(log);
- va_end(arg);
- }
- }
- /******************************************************************
- * M O V E _ T O _ F I E L D
- * -------------------------
- * Description:
- * Internal function to do the actual move of the field.
- *
- * Arguments:
- * fld - Pointer to field to move to.
- *
- ******************************************************************/
- static void
- move_to_field(struct field *fld)
- {
- if (fld == NULL)
- {
- fld = _cf_globals.field;
- }
-
- /*
- * Repeat moving from and to fields while their event routines
- * calles the fld_move.
- */
- do
- {
- /*
- * First move from a field.
- */
- _cf_globals.move_field = NULL;
- if (_cf_globals.field) {
- raw_event(EVENT_EXIT, 0, 0);
- if (_cf_globals.move_field != NULL)
- {
- fld = _cf_globals.move_field;
- }
- }
-
- /*
- * Then move to a field.
- */
- _cf_globals.field = fld;
- _cf_globals.move_field = NULL;
- raw_event(EVENT_ENTRY, 0, 0);
- fld = _cf_globals.move_field;
-
- } while (_cf_globals.move_field != NULL);
- }
-